This section is a top down look at how Formtastic works. It also reviews Formtastic's table column naming convention for associated tables.

Experienced Rails developers can skip this topic with the possible exception of "Table Column Naming Convention":#attribute_naming .

"These example files":http://wiki.github.com/justinfrench/formtastic/7-example-code and tables based on "these migration files":http://wiki.github.com/justinfrench/formtastic/7-example-code#migration_file_books are used throughout the Formtastic wiki help pages.

The example files combined with this short Formtastic code block

<pre>
<%= semantic_form_for @book do |form| %>
    <%= form.inputs %>
    <%= form.buttons %>
<% end %>
</pre>

generates "this HTML form:":https://github.com/formtastic/formtastic/wiki/7.1-Example-Rendered-HTML

A lot of form for a little Formtastic. Let's look at how it's done.

Formtastic can determine column names and data types of the table "books" via the model class Book (a sub-class of Active Record) and Book's object @book.   

Active Record is "Rails version of ORM":http://en.wikipedia.org/wiki/Object-relational_mapping . Here's a debug listing of the @book object used by the Formtastic code block shown above:

<pre>
<%= debug(@book.class)%>

outputs this information:

Book(id: integer, title: string, description: text, still_in_print: boolean,
 published: date, isbn_number: integer, price: decimal,
 publisher_id: integer, created_at: datetime,
 updated_at: datetime)
</pre>

The listing shows that the instance variable @book is an object of the model class Book. So @book via the Book model and Active Record gives access to the books table's column names and data types. 

Formtastic, through the model object @book, can cobble together the HTML form inputs by data type and label each input with the corresponding table column name.

The HTML form that is rendered by Formtastic, by convention, does not render the books table's primary key (@id@), nor the foreign key @publisher_id@ (required for the @belongs_to@ association with the model @Publisher@), nor does it render the @created_at@ and @updated_at@ model attributes.

This, in large part, is how the form and its inputs can be generated from only four lines of Formtastic code. Formtastic,however, does more than just render the books' table columns as form inputs. It can also render form inputs that deal with tables that are associated with the books table - in the case of the example, the publishers table. 

The associated authors and format_types tables are not included in the HTML generated by the four line Formtastic code block. It will be explained later how they can be included as multi-select inputs with insertion of some additional Formtastic code.

<a name="attribute_naming"></a> 

h4. Associated Tables - Table Column Naming Convention

In addition to rendering HTML form inputs for the books' table columns, Formtastic also renders a select input labelled "Publisher" that lists book publishers. Here's an example of the select input with some content

<pre>
<label for="book_publisher_id">Publisher<abbr title="required">*</abbr></label>
<select id="book_publisher_id" name="book[publisher_id]"><option value=""></option> 
<option value="1">The Pragmatic Bookshelf</option> 
<option value="2">sitepoint</option> 
<option value="3">O'Reilly</option></select>
</pre>

The select's values and labels (e.g. 1 and "The Pragmatic Bookshelf") are populated using data from the publishers table - the value is from the publishers table's primary key @id@ and the labels are from its @name@ column.
 
This select is created based on the Book model's @belongs_to@ association with the Publisher model - i.e. the Book model   @belongs_to => :publisher@. The Publisher model is associated with the Book model by the association @has_many => :books@. In plain English; a book has one publisher (per our example at least) and a publisher publishes many books.

This is where an explanation of the Formtastic table column naming convention is needed.

The @books@ table has a foreign key @publisher_id@ that gets its data from the publisher input select value - this data is the value of the publishers tables' primary key @id@ for a given Publisher name. It's easy enough to understand how Formtastic can determine and populate the select value with the @publishers@ table's primary key @id@ column since it is a Rails convention that tables include a primary key column named @id@.

The question that can be asked is : "How does Formtastic know which publishers table column to use for the labeling the select values? ".

A good question since the publishers table could have many columns. This is where the Formtastic's column naming convention comes into play.

For associated tables (publishers, authors and format_types in the example), the convention is that Formtastic looks for a column with one of the following names: @to_label, display_name, full_name, name, title, username, login and value@. Any column with one of these names is used to populate the labels within the select input.

If you check the rendered HTML, only one select input is created and it's for the @belongs_to@ association with the @Publisher@ model. There are no multi-selects, rendered for the associations with the @authors@ and @format_types@ models.

In order to have the Formtastic code block include the @authors@ and @format_types@ as multi-select inputs, there is a requirement to explicitly identify which @Book@ model attributes to include in the rendered form and, as well as, _which associated models to include_.  

This code block:

<pre>
<% semantic_form_for @book do |form| %>
    <%= form.inputs %>
    <%= form.buttons %>
<% end %>
</pre>

needs to be expanded to to include the @Book@ model attribute names and the plural lowercase of the habtm model names @authors@ and @format_types@ and singular lowercase of the publisher model name - @publisher@:

<pre>
<% semantic_form_for @book do |form| %>
    <%= form.inputs :title, :description, :still_in_print, :published,
            :isbn_number, :price, :publisher, :authors, :format_types %>
    <%= form.buttons %>
<% end %>
</pre>

Just to be clear, the options listed after the form.inputs method are a mix of @book attribute names and associated model names.

Formtastic's naming convention can be overridden. If someone prefers to have the authors table use author_name instead of name to identify the author and have it included in the select as the values label then the following code change is needed:

<pre>
<% semantic_form_for $model$ do |form| %>
  <% form.inputs do -%>
    <%= form.input :name %>
    <%= form.input :description %>
    <%= form.input :still_in_print%>
    <%= form.input :published%>
    <%= form.input :isbn_number%>
    <%= form.input :price%>
    <%= form.input :authors, :member_label => author_name%>
    <%= form.input :format_types%>
  <% end %>
<% end %>
</pre>

Finally, just as there is the :member_label to override which table column data is used to populate the select's labels there is also a :member_value to override which table column is used to populate the select's values. 